added SSCLI 1.0
[windows-sources.git] / shared source / sscli20 / samples / compilers / myc / src / emit.cs
blob5fc899d0032ab7429be44a5e610317d8188cb1ef
1 //------------------------------------------------------------------------------
2 // <copyright file="emit.cs" company="Microsoft">
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 // </copyright>
14 //------------------------------------------------------------------------------
16 namespace MyC
19 * the emit routines add "instruction" to the instruction stream (istream)
20 * currently the istream is flushed when the emitAsm routine is called
22 using System;
23 using System.Reflection;
25 class Emit
27 IAsm iroot; // root of current instruction list
28 IAsm icur; // current insn ptr
29 IAsm LastComment; // ptr to last comment placeholder
31 VarList localvars; // local copy of current localvar list
33 Io io; // local copy of current IO handle
35 Exe exe; // instance of exe class for generation
38 * get the function definition entry
40 public Var GetFunc()
42 IAsm a;
43 if (iroot == null)
44 return null;
45 a = iroot;
46 while (a != null)
48 if (a.getIType() == IAsm.I_FUNC_BEGIN)
49 return (a.getVar());
50 a = a.getNext();
52 return null; /* didn't find anything */
55 void NextInsn(int incr)
57 int ncount = 0;
58 if (iroot == null)
60 icur = iroot = new IAsm();
62 else
64 ncount = icur.getICount() + incr; /* propogate previous count */
65 icur.setNext(new IAsm());
66 icur = icur.getNext();
68 icur.setICount(ncount);
72 * Emit a field def to ilist
74 public void FieldDef(Var e)
76 NextInsn(0);
77 icur.setIType(IAsm.I_FIELD);
78 icur.setVar(e);
82 * Emit function begin to ilist
84 public void FuncBegin(Var e)
86 NextInsn(0);
87 icur.setIType(IAsm.I_FUNC_BEGIN);
88 icur.setVar(e);
92 * Emit the local declarations
94 public void LocalVars(VarList v)
96 NextInsn(0);
97 localvars = v;
98 icur.setIType(IAsm.I_LOCALDEF);
102 * Emit instruction to ilist
104 public void Insn(String s)
106 NextInsn(1);
107 icur.setIType(IAsm.I_INSN);
108 icur.setInsn(s);
111 public void Label(String lname)
112 { // this is the branch target
113 NextInsn(0);
114 icur.setIType(IAsm.I_LABEL);
115 icur.setLabel(lname);
118 public void Branch(String s, String lname)
119 { // this is the branch source
120 NextInsn(1);
121 icur.setIType(IAsm.I_BRANCH);
122 icur.setInsn(s);
123 icur.setLabel(lname);
126 public void Store(Var e)
128 NextInsn(1);
129 icur.setIType(IAsm.I_INSN_STORE);
130 icur.setVar(e);
133 public void Load(Var e)
135 NextInsn(1);
136 icur.setIType(IAsm.I_INSN_LOAD);
137 icur.setVar(e);
140 public void LoadConst(String s)
142 NextInsn(1);
143 icur.setIType(IAsm.I_INSN_LOAD_CONST);
144 icur.setInsn(s);
147 public void Call(Var e)
149 NextInsn(1);
150 icur.setIType(IAsm.I_CALL);
151 icur.setVar(e); /* this is the callname */
154 public void Finish()
156 iroot = icur = null;
159 public void CommentHolder()
161 NextInsn(0);
162 icur.setIType(IAsm.I_COMMENT);
163 LastComment = icur; /* save away this insn loc to store comment */
164 icur.setCommentLine(io.commentGetCurrentLine());
167 public void CommentFill(String comment)
169 #if DEBUG
170 Console.Write("CommentFill S=");
171 for (int _debug_i=0; _debug_i<comment.Length;_debug_i++)
173 int _debug_d = comment[_debug_i];
174 char _debug_c = (char) (_debug_d + 96);
175 if (_debug_d < 32)
176 Console.Write("^"+_debug_c);
177 else
178 Console.Write(comment[_debug_i]);
179 Console.Write("[");
180 Console.Write(_debug_d);
181 Console.Write("],");
183 Console.WriteLine(";");
184 #endif
185 if (LastComment != null)
186 LastComment.setComment(comment);
189 public void Ret()
191 NextInsn(1);
192 icur.setIType(IAsm.I_RET);
195 public void FuncEnd()
197 NextInsn(0);
198 icur.setIType(IAsm.I_FUNC_END);
202 * Emit exe instructions now
203 * this flushes the istream
205 public void IL()
207 IAsm a = iroot;
208 IAsm p;
210 while (a != null)
212 switch (a.getIType())
214 case IAsm.I_INSN:
215 exe.Insn(a);
216 break;
217 case IAsm.I_LABEL:
218 exe.Label(a);
219 break;
220 case IAsm.I_BRANCH:
221 exe.Branch(a);
222 break;
223 case IAsm.I_INSN_STORE:
224 exe.Store(a);
225 break;
226 case IAsm.I_INSN_LOAD:
227 exe.Load(a);
228 break;
229 case IAsm.I_INSN_LOAD_CONST:
230 exe.LoadConst(a);
231 break;
232 case IAsm.I_FUNC_BEGIN:
233 exe.FuncBegin(a); /* Emit function beginning */
234 break;
235 case IAsm.I_FUNC_END:
236 exe.FuncEnd();
237 break;
238 case IAsm.I_CALL:
239 exe.Call(a);
240 break;
241 case IAsm.I_RET:
242 exe.Ret(a);
243 break;
244 case IAsm.I_FIELD:
245 exe.FieldDef(a);
246 break;
247 case IAsm.I_LOCALDEF:
248 exe.LocalVars(localvars);
249 break;
250 case IAsm.I_COMMENT:
251 exe.Comment(a);
252 break;
253 default:
254 io.Abort("Unhandled instruction type " + a.getIType());
255 break;
257 p = a;
258 a = a.getNext();
263 * Emit assembly instructions now
264 * this flushes the istream
266 public void LIST()
268 IAsm a = iroot;
269 IAsm p;
270 Asm x = new Asm(io);
272 while (a != null)
274 switch (a.getIType())
276 case IAsm.I_INSN:
277 x.Insn(a);
278 break;
279 case IAsm.I_LABEL:
280 x.Label(a);
281 break;
282 case IAsm.I_BRANCH:
283 x.Branch(a);
284 break;
285 case IAsm.I_INSN_STORE:
286 x.Store(a);
287 break;
288 case IAsm.I_INSN_LOAD:
289 x.Load(a);
290 break;
291 case IAsm.I_INSN_LOAD_CONST:
292 x.LoadConst(a);
293 break;
294 case IAsm.I_FUNC_BEGIN:
295 x.FuncBegin(a); /* Emit function beginning */
296 break;
297 case IAsm.I_FUNC_END:
298 x.FuncEnd();
299 break;
300 case IAsm.I_CALL:
301 x.Call(a);
302 break;
303 case IAsm.I_RET:
304 x.Ret(a);
305 break;
306 case IAsm.I_COMMENT:
307 x.Comment(a);
308 break;
309 case IAsm.I_FIELD:
310 x.FieldDef(a);
311 break;
312 case IAsm.I_LOCALDEF:
313 x.LocalVars(localvars);
314 break;
315 default:
316 io.Abort("Unhandled instruction type " + a.getIType());
317 break;
319 p = a;
320 a = a.getNext();
324 public void BeginModule()
326 exe.BeginModule(io.GetInputFilename());
329 public void BeginClass()
331 exe.BeginClass(Io.GetClassname(), TypeAttributes.Public);
332 if (Io.genlist)
333 io.Out(".class " + Io.GetClassname() + "{\r\n");
336 public void EndClass()
338 exe.EndClass();
339 if (Io.genlist)
340 io.Out("}\r\n");
343 public void EndModule()
345 exe.EndModule();
348 public Emit(Io o)
350 io = o;
351 exe = new Exe(Io.GetClassname());